from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator, MaxValueValidator
import os

from django.db.models.signals import pre_delete
from django.dispatch import receiver
from django.core.files.storage import default_storage
        
# 基类，包含用户字段
class UserOwnedModel(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)

    class Meta:
        abstract = True

# 分类模型
class Category(UserOwnedModel):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class SubCategory(models.Model):
    name = models.CharField(max_length=20)
    parent = models.ForeignKey(Category, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

# 颜色模型
class Color(UserOwnedModel):
    name = models.CharField(max_length=20)
    rgb = models.CharField(max_length=20)

    def __str__(self):
        return self.name

# 位置模型
class StorageLocation(UserOwnedModel):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

# 品牌模型
class Brand(UserOwnedModel):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

# 尺码类型模型
class SizeType(UserOwnedModel):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

# 尺码模型
class Size(models.Model):
    name = models.CharField(max_length=10)
    parent = models.ForeignKey(SizeType, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

# 材质模型
class Material(UserOwnedModel):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

# 标签类型模型
class TagType(UserOwnedModel):
    mode = models.CharField(max_length=20, null=True, blank=True)
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

# 标签模型
class Tag(models.Model):
    parent = models.ForeignKey(TagType, on_delete=models.CASCADE, related_name='tags', default=1)
    name = models.CharField(max_length=100)

    def __str__(self):
        return f"{self.parent}: {self.name}"

def get_other_image_path(instance, filename):
    return os.path.join('closet', instance.user.username, instance.image_type, 'other', filename)
def get_clothes_image_path(instance, filename):
    return os.path.join('closet', instance.user.username, 'clothes', filename)
def get_suits_image_path(instance, filename):
    return os.path.join('closet', instance.user.username, 'suits', filename)

# 图片模型
class Image(UserOwnedModel):
    image = models.ImageField(upload_to=get_other_image_path)
    image_type = models.CharField(max_length=20)  # 'clothes', 'suits', etc.
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"Image {self.id}"
    def delete(self, *args, **kwargs):
        # 删除图片文件
        if self.image:
            if os.path.isfile(self.image.path):
                default_storage.delete(self.image.path)
        # 调用模型的原始delete方法来删除数据库记录
        super(Image, self).delete(*args, **kwargs)

# 季节选项
class Season(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):
        return self.name

# 厚度模型
class Thickness(UserOwnedModel):
    name = models.CharField(max_length=10)
    description = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.name

# 衣服模型
class Clothes(UserOwnedModel):
    main_image = models.ImageField(upload_to=get_clothes_image_path, null=True, blank=True)
    name = models.CharField(max_length=255)
    sub_category = models.ForeignKey(SubCategory, on_delete=models.CASCADE, related_name='clothes')
    colors = models.ManyToManyField(Color, related_name='clothes', blank=True)
    seasons = models.ManyToManyField(Season, related_name='clothes', blank=True) 
    thickness = models.ForeignKey(Thickness, on_delete=models.SET_NULL, null=True, blank=True)  # 关联到厚度模型
    storage_location = models.ForeignKey(StorageLocation, on_delete=models.CASCADE, related_name='clothes', null=True, blank=True)
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='clothes', null=True, blank=True)
    price = models.DecimalField(
        max_digits=10, decimal_places=2,
        validators=[MinValueValidator(0.0)],
        null=True, blank=True
    )
    sizes = models.ManyToManyField(Size, related_name='clothes', blank=True)
    purchase_link = models.URLField(null=True, blank=True)
    purchase_date = models.DateField(null=True, blank=True)
    materials = models.ManyToManyField(Material, through='ClothesMaterial', blank=True)
    tags = models.ManyToManyField(Tag, related_name='clothes', blank=True)
    notes = models.CharField(max_length=255, null=True, blank=True)
    other_images = models.ManyToManyField(Image, related_name='clothes', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name
    def delete(self, *args, **kwargs):
        # 删除关联的other_images
        for image in self.other_images.all():
            image.delete()
        # 删除main_image文件
        if self.main_image:
            if os.path.isfile(self.main_image.path):
                default_storage.delete(self.main_image.path)
        # 调用模型的原始delete方法来删除数据库记录
        super(Clothes, self).delete(*args, **kwargs)

# 衣服材质关系模型
class ClothesMaterial(models.Model):
    clothes = models.ForeignKey(Clothes, on_delete=models.CASCADE)
    material = models.ForeignKey(Material, on_delete=models.CASCADE)
    percentage = models.DecimalField(
        max_digits=5, decimal_places=2, default=100,
        validators=[MinValueValidator(0), MaxValueValidator(100)]
    )

    def __str__(self):
        return f"{self.clothes.name} - {self.material.name} ({self.percentage}%)"

# 套装模型
class Suits(UserOwnedModel):
    main_image = models.ImageField(upload_to=get_suits_image_path, null=True, blank=True)
    name = models.CharField(max_length=255)
    tags = models.ManyToManyField(Tag, related_name='suits', blank=True)
    notes = models.CharField(max_length=255, null=True, blank=True)
    other_images = models.ManyToManyField(Image, related_name='suits', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name
    def delete(self, *args, **kwargs):
        # 删除关联的other_images
        for image in self.other_images.all():
            image.delete()
        # 删除main_image文件
        if self.main_image:
            if os.path.isfile(self.main_image.path):
                default_storage.delete(self.main_image.path)
        # 调用模型的原始delete方法来删除数据库记录
        super(Clothes, self).delete(*args, **kwargs)
        
# 信号接收器，在删除Clothes或Suits实例时删除关联的图片
@receiver(pre_delete, sender=Clothes)
@receiver(pre_delete, sender=Suits)
def delete_associated_images(sender, instance, **kwargs):
    if sender == Clothes:
        for image in instance.other_images.all():
            image.delete()
    elif sender == Suits:
        for image in instance.other_images.all():
            image.delete()

# 位置模型
class LocationInfo(models.Model):
    latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
    longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
    altitude = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True)
    location_name = models.CharField(max_length=100)

    def __str__(self):
        return self.location_name

# 天气状态模型
class WeatherCondition(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

# 体感状态模型
class Feeling(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

# 记录模型
class Record(UserOwnedModel):
    date = models.DateField()
    clothes = models.ManyToManyField(Clothes, related_name='records', blank=True)
    suits = models.ManyToManyField(Suits, related_name='records', blank=True)

    location = models.ForeignKey(LocationInfo, on_delete=models.SET_NULL, related_name='weather_info', null=True, blank=True)
    min_temperature = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    max_temperature = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    weather_condition = models.ForeignKey(WeatherCondition, on_delete=models.SET_NULL, related_name='weather_info', null=True, blank=True)
    wind_level = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    feeling = models.ForeignKey(Feeling, on_delete=models.SET_NULL, related_name='weather_info', null=True, blank=True)
    feels_like = models.CharField(max_length=50, null=True, blank=True)

    def __str__(self):
        return f"Record on {self.date}"
    
    class Meta:
        unique_together = [('user', 'date')]  # 同一用户每天只能有一条记录
